package com.example.smartpark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartpark.dto.UserDTO;
import com.example.smartpark.dto.UserQueryDTO;
import com.example.smartpark.dto.VehicleDTO;
import com.example.smartpark.exception.BusinessException;
import com.example.smartpark.mapper.UserMapper;
import com.example.smartpark.mapper.VehicleMapper;
import com.example.smartpark.model.User;
import com.example.smartpark.model.Vehicle;
import com.example.smartpark.service.SystemConfigService;
import com.example.smartpark.service.UserAdminService;
import com.example.smartpark.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户管理服务实现类
 */
@Slf4j
@Service
public class UserAdminServiceImpl extends ServiceImpl<UserMapper, User> implements UserAdminService {

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private VehicleMapper vehicleMapper;

    private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public IPage<UserDTO> getUserPage(UserQueryDTO queryDTO) {
        log.info("分页查询用户列表: {}", queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.hasText(queryDTO.getUsername())) {
            queryWrapper.like(User::getUsername, queryDTO.getUsername());
        }
        
        if (StringUtils.hasText(queryDTO.getRealName())) {
            queryWrapper.like(User::getRealName, queryDTO.getRealName());
        }
        
        if (StringUtils.hasText(queryDTO.getPhone())) {
            queryWrapper.like(User::getPhone, queryDTO.getPhone());
        }
        
        if (queryDTO.getRole() != null) {
            queryWrapper.eq(User::getRole, queryDTO.getRole());
        }
        
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(User::getStatus, queryDTO.getStatus());
        }
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc(User::getCreatedAt);
        
        // 执行分页查询
        Page<User> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        IPage<User> resultPage = this.page(page, queryWrapper);
        
        // 转换为 DTO
        IPage<UserDTO> dtoPage = resultPage.convert(this::convertToDTO);
        
        return dtoPage;
    }

    @Override
    public UserDTO getUserById(Integer id) {
        log.info("获取用户详情: {}", id);
        
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        return convertToDTO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO createUser(UserDTO userDTO) {
        log.info("创建用户: {}", userDTO);
        
        // 检查用户名是否已存在
        checkUsernameExists(userDTO.getUsername(), null);
        
        // 构建用户实体
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        
        // 设置密码（如果没有提供密码，则使用系统默认密码）
        String password = userDTO.getPassword();
        if (!StringUtils.hasText(password)) {
            password = systemConfigService.getSystemConfig().getDefaultPassword();
        }
        user.setPassword(MD5Utils.encrypt(password));
        
        // 设置默认状态和角色
        if (user.getStatus() == null) {
            user.setStatus(1); // 默认启用
        }
        
        if (user.getRole() == null) {
            user.setRole(0); // 默认普通用户
        }
        
        // 保存用户
        if (!this.save(user)) {
            throw new BusinessException("创建用户失败");
        }
        
        return convertToDTO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO updateUser(Integer id, UserDTO userDTO) {
        log.info("更新用户: id={}, data={}", id, userDTO);
        
        // 检查用户是否存在
        User existingUser = this.getById(id);
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 检查用户名是否已存在（排除当前用户）
        if (StringUtils.hasText(userDTO.getUsername())) {
            checkUsernameExists(userDTO.getUsername(), id);
        }
        
        // 更新用户信息
        BeanUtils.copyProperties(userDTO, existingUser, "id", "password", "createdAt", "updatedAt");
        existingUser.setId(id);
        
        // 如果提供了新密码，则更新密码
        if (StringUtils.hasText(userDTO.getPassword())) {
            existingUser.setPassword(MD5Utils.encrypt(userDTO.getPassword()));
        }
        
        // 保存更新
        if (!this.updateById(existingUser)) {
            throw new BusinessException("更新用户失败");
        }
        
        return convertToDTO(existingUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Integer id) {
        log.info("删除用户: {}", id);
        
        // 检查用户是否存在
        User existingUser = this.getById(id);
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 删除用户
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO changeUserStatus(Integer id, Integer status) {
        log.info("更改用户状态: id={}, status={}", id, status);
        
        // 检查用户是否存在
        User existingUser = this.getById(id);
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 检查状态值是否有效
        if (status != 0 && status != 1) {
            throw new BusinessException("无效的状态值");
        }
        
        // 更新状态
        existingUser.setStatus(status);
        
        // 保存更新
        if (!this.updateById(existingUser)) {
            throw new BusinessException("更改用户状态失败");
        }
        
        return convertToDTO(existingUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetUserPassword(Integer id) {
        log.info("重置用户密码: {}", id);
        
        // 检查用户是否存在
        User existingUser = this.getById(id);
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 获取系统默认密码并重置
        String defaultPassword = systemConfigService.getSystemConfig().getDefaultPassword();
        existingUser.setPassword(MD5Utils.encrypt(defaultPassword));
        
        // 保存更新
        return this.updateById(existingUser);
    }
    
    /**
     * 检查用户名是否已存在
     *
     * @param username 用户名
     * @param excludeId 排除的用户ID（用于更新时）
     */
    private void checkUsernameExists(String username, Integer excludeId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        
        if (excludeId != null) {
            queryWrapper.ne(User::getId, excludeId);
        }
        
        if (this.count(queryWrapper) > 0) {
            throw new BusinessException("用户名已存在");
        }
    }
    
    /**
     * 转换用户实体为DTO
     *
     * @param user 用户实体
     * @return 用户DTO
     */
    private UserDTO convertToDTO(User user) {
        if (user == null) {
            return null;
        }

        UserDTO dto = new UserDTO();
        BeanUtils.copyProperties(user, dto);
        
        // 格式化日期时间
        if (user.getCreatedAt() != null) {
            dto.setCreatedAt(DATE_FORMATTER.format(user.getCreatedAt()));
        }
        if (user.getUpdatedAt() != null) {
            dto.setUpdatedAt(DATE_FORMATTER.format(user.getUpdatedAt()));
        }

        // 加载用户的车辆信息
        LambdaQueryWrapper<Vehicle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Vehicle::getUserId, user.getId());
        List<Vehicle> vehicles = vehicleMapper.selectList(queryWrapper);

        // 转换车辆信息为DTO
        List<VehicleDTO> vehicleDTOs = vehicles.stream().map(vehicle -> {
            VehicleDTO vehicleDTO = new VehicleDTO();
            BeanUtils.copyProperties(vehicle, vehicleDTO);
            
            // 格式化车辆的日期时间
            if (vehicle.getCreatedAt() != null) {
                vehicleDTO.setCreatedAt(DATE_FORMATTER.format(vehicle.getCreatedAt()));
            }
            if (vehicle.getUpdatedAt() != null) {
                vehicleDTO.setUpdatedAt(DATE_FORMATTER.format(vehicle.getUpdatedAt()));
            }
            
            return vehicleDTO;
        }).collect(Collectors.toList());

        dto.setVehicles(vehicleDTOs);
        
        return dto;
    }
} 